#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on Wed Mar 27 23:56:57 2013

@author: nicola
"""

import re
import os
import os.path

from kelindo.formats import MusicFile

class FolderError(Exception): pass

class Folder(object):     
    def __init__(self, path, status, tracks):
        self.path = path
        self.status = status
        self.tracks = tracks
        self.distance = 0.0
        self.candidate = None
        return
        
    @staticmethod
    def __coherent_track_numbers(tracks):
        """ Checks if track numbers are coherent """
        try:
            tracks = sorted(tracks, key=lambda track: int(track['tracknumber']))
            pos = 1   
            for track in tracks:
                if int(track['tracknumber']) != pos:
                    return False
                pos += 1
            return True
        except:
            return False
        
    @staticmethod
    def __get_track_numbers(tracks):
        """ Retrieves track numbers using several strategies """
           
        # 1st strategy, track numbers from metadata
        if Folder.__coherent_track_numbers(tracks): return True
        
        # 2nd strategy, track numbers from filename
        for track in tracks:
            match = re.search('(\d{1,2})', track['~filename'])
            if match:
                track['tracknumber'] = unicode(int(match.groups()[0])) 
        if Folder.__coherent_track_numbers(tracks): return True
                        
        return False
    
    @staticmethod
    def folder_factory(path):
        """ Build folder attributes """
        tracks = []
        for filename in os.listdir(path):
            track = MusicFile(os.path.join(path, filename))
            if track is not None: tracks.append(track)
                
        if (len(tracks) == 0):
            return NO_MEDIA_Folder(path, tracks)
        
        if (len(tracks) > 99):
            return TOOMANY_MEDIA_Folder(path, tracks)
            
        if not Folder.__get_track_numbers(tracks):
            return NO_TNUMBERS_Folder(path, tracks)
            
        tracks = sorted(tracks, key=lambda track: int(track['tracknumber']))
        return OK_Folder(path, tracks)
        
        
    def __repr__(self):
        out = []
        out.append('%s, %s' % (self.status, self.path,)) 
        return '\n'.join(out)
        
        
    def get_durations(self):
        """ Returns the list of files durations """
        raise FolderError
        
        
    def get_format(self):
        """  Returns media format of the folder """
        raise FolderError
        
        
    def get_bitrate(self):
        """ Returns average bitrate of the folder """
        raise FolderError
            
        
class NO_TNUMBERS_Folder(Folder):
    def __init__(self, path, tracks):
        super(NO_TNUMBERS_Folder, self).__init__(path, 'NO_TNUMBERS', tracks)
        return

        
class NO_MEDIA_Folder(Folder):
    def __init__(self, path, tracks):
        super(NO_MEDIA_Folder, self).__init__(path, 'NO_MEDIA', tracks)
        return

        
class TOOMANY_MEDIA_Folder(Folder):
    def __init__(self, path, status, tracks):
        super(TOOMANY_MEDIA_Folder, self).__init__(path, 'TOOMANY_MEDIA', tracks)
        return


class OK_Folder(Folder):     
    def __init__(self, path, tracks):
        super(OK_Folder, self).__init__(path, 'OK', tracks)
        return
        
        
    def __repr__(self):
        out = []
        out.append('%s, %s, %d tracks, %s, %dkbps' % (
            self.status, 
            self.path, 
            len(self.tracks),
            self.get_format(),
            self.get_bitrate()))
            
        for track in self.tracks:
            out.append(track.__repr__())
            
        if self.candidate is not None:
            for track in self.candidate:
                out.append(track.__repr__())
            
        return '\n'.join(out)
        
        
    def get_durations(self):
        durations = []
        for track in self.tracks:
            durations.append(track['~#length'])
        return durations
        
        
    def get_format(self):
        """  Returns media format of the folder """
        return
        
        
    def get_bitrate(self):
        """ Returns average bitrate of the folder """
        bitrate = 0
        for track in self.tracks:
            bitrate += track['~#bitrate']
        return bitrate / len(self.tracks)
        
